package mmc.action;

import mmc.EngineObject;
import mmc.resource.Sprite2D;
import mmc.server.RemoteClient;
import mmc.server.Server;

public abstract class Action implements Comparable<Action> {	
	public String name;
	public Sprite2D texture;
	public int defaultKey;
	public String description;
	
	public Action(String name, Sprite2D texture, int defaultKey){
		this.name = name;
		this.defaultKey = defaultKey;
		this.texture = texture;
	}
	
	public Action(String name, String textureName, int defaultKey){
		this(name, (mmc.Constants.IS_SERVER || textureName==null)?null:new Sprite2D(textureName), defaultKey);
	}
	
	public abstract void performOnClient();
	public void performOnServer(RemoteClient client, int targetId) throws TargetException{
		throw new RuntimeException("not implemented");
	}
	
	/**
	 * Range of this Action
	 * @return -1 is infinite range
	 */
	public float getRange(){
		return -1;
	}
	
	public EngineObject resolveTarget(RemoteClient client, int targetId) throws TargetException{
		EngineObject target = Server.instance.getScene().objects.get(targetId);

		if(target==null)
			throw new TargetException("Target not found!");
		
		float range = getRange();
		if(range!=-1 && !client.getPlayer().inRange(target, range))
			throw new TargetException("Target out of range!");
		
		return target;
	}
	
    @Override
    public int compareTo(Action other) {    
    	if(this.getClass().getSuperclass() == other.getClass().getSuperclass())
    		return name.compareTo(other.name);
    	else
    		return this.getClass().getSuperclass().getName().compareTo(other.getClass().getSuperclass().getName());
    }
       
    @Override 
    public String toString(){
    	return this.getClass().getName();
    }
    
    private volatile int hashCode = 0;
	public boolean equals(Object obj) {
        if(this == obj) {
            return true;
        }
        if (!(obj instanceof Action)) {
            return false; 
        }
        
        Action person = (Action)obj;
        return name.equals(person.name);	 
    }
	 
    public int hashCode () {
        final int multiplier = 23;
        if (hashCode == 0) {
            int code = 133;
            code = multiplier * code + name.hashCode();
            hashCode = code;
        }
        return hashCode;
    }
}
